
import latisi.events.SelectionEvent;

private var selectionSprite:Sprite;
private var selectionRectangle:Rectangle;
private var selectionPoint:Point;
private var selectableObject:Object;

private function addSelectionBoxHandlers(object:Object):void{
  selectableObject = object;
  selectableObject.addEventListener(MouseEvent.MOUSE_DOWN, drawSelectionBox);
  selectableObject.addEventListener(MouseEvent.MOUSE_UP, eraseSelectionBox);
}

private function drawSelectionBox(event:MouseEvent):void{
  trace("mouse down for selection box");
  // stop
  selectionSprite = new Sprite();
  selectionPoint = new Point(selectableObject.mouseX, selectableObject.mouseY);
  selectionRectangle = new Rectangle(selectionPoint.x, selectionPoint.y, 1, 1);
  selectionSprite.graphics.lineStyle(1);
  //selectionSprite.graphics.beginFill(0x0000FF, 0.5);
  selectionSprite.graphics.drawRect(selectionPoint.x, selectionPoint.y, 1, 1);
  //selectionSprite.graphics.endFill();
  selectableObject.addChildAt(selectionSprite, 1);
  addEventListener(MouseEvent.MOUSE_MOVE, updateSelectionBox);
  // notify everyone to refresh select list
  dispatchSelectionEvent(SelectionEvent.UPDATE);
}

private function eraseSelectionBox(event:MouseEvent):void{
  removeEventListener(MouseEvent.MOUSE_MOVE, updateSelectionBox);
  if (selectionSprite) {
    // notify anyone who cares of what got selected
    dispatchSelectionEvent(SelectionEvent.DONE);
    selectableObject.removeChild(selectionSprite);
    selectionSprite = null;
    selectionPoint = null;
    selectionRectangle = null;
  }
}

private function updateSelectionBox(event:MouseEvent):void{
  selectionRectangle.width = selectableObject.mouseX - selectionPoint.x;
  selectionRectangle.height = selectableObject.mouseY - selectionPoint.y;
  selectionSprite.graphics.clear();
  selectionSprite.graphics.lineStyle(1);
  //selectionSprite.graphics.beginFill(0x0000FF, 0.5);
  selectionSprite.graphics.drawRect(selectionPoint.x, 
				    selectionPoint.y,
				    selectionRectangle.width,
				    selectionRectangle.height);
  //selectionSprite.graphics.endFill();
  dispatchSelectionEvent(SelectionEvent.UPDATE);
}

private function dispatchSelectionEvent(type:String):void {
  var objects:Array = getSelections(selectionRectangle);
  var updateEvent:SelectionEvent = new SelectionEvent(type);
  updateEvent.selectedObjects = objects[0];
  updateEvent.notSelectedObjects = objects[1];
  dispatchEvent(updateEvent);
}

private function getSelections(rect:Rectangle):Array {
  var intersected:Array = new Array();
  var notIntersected:Array = new Array();
  rect = positiveRect(rect);
  for (var i:int = 0; i < selectableObject.numChildren; i++) {
    // add each intersecting object to an array
    if (rect.intersects(selectableObject.getChildAt(i).getRect(selectableObject))) {
      intersected.push(selectableObject.getChildAt(i));
    } else {
      notIntersected.push(selectableObject.getChildAt(i));
    }
  }
  return [intersected, notIntersected];
}

private function positiveRect(rect:Rectangle):Rectangle {
  var pRect:Rectangle = rect.clone();
  if (rect.width < 0) { 
    pRect.x = rect.x + rect.width;
    pRect.width *= -1;
  }
  if (rect.height < 0) { 
    pRect.y = rect.y + rect.height;
    pRect.height *= -1;
  }
  return pRect;
}